/* ---------------------------------------------------------------------------
   (c) Copyright 2006 ActivIdentity, Inc.
   All Rights Reserved.

   This program is an unpublished copyrighted work which is proprietary
   to ActivIdentity. This computer program includes Confidential,
   Proprietary Information and is a Trade Secret of ActivIdentity.
   Any use, disclosure, modification and/or reproduction is prohibited
   unless authorized in writing by ActivIdentity.

   WARNING:  Unauthorized reproduction of this program as well as
   unauthorized preparation of derivative works based upon the
   program or distribution of copies by sale, rental, lease or
   lending are violations of federal copyright laws and state trade
   secret laws, punishable by civil and criminal penalties.
   --------------------------------------------------------------------------- */

/* ---------------------------------------------------------------------------
   Disclaimer

   ACTIVIDENTITY MAKES NO REPRESENTATIONS OR WARRANTIES WITH RESPECT TO THE 
   CONTENTS OR USE OF THIS SOFTWARE, AND SPECIFICALLY DISCLAIMS ANY EXPRESS
   OR IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR
   PURPOSE. Further, ActivIdentity reserves the right to revise this software
   and to make changes to its content, at any time, without obligation to
   notify any person or entity of such revisions or changes.
   --------------------------------------------------------------------------- */

#ifndef __SDBAPI_H__
#define __SDBAPI_H__

#ifdef __cplusplus
extern "C" {
#endif

#if defined(WIN32) || defined(_WIN32_WCE)
/* Windows standard files and definitions */
#include <windows.h>
#else
/* Unix standard files and definitions */
#include <stdio.h>
#define CALLBACK
#define TRUE 1
#define FALSE 0
#endif


/***************/
/** CONSTANTS **/
/***************/
#define IN
#define OUT
#define INOUT


/* Sizes */
#define SDB_SERVICE_NAME_SIZE	                (16+1)
#define SDB_CONTENT_ID_SIZE		                (16+1)
#define SDB_CONTENT_ID_SIZE_HEXDEC	            (32+1)

/* Service types */
#define	SDB_SERVICETYPE_TOKEN_GENERALDATA				1
#define	SDB_SERVICETYPE_TOKEN_MESSAGES					2
#define SDB_SERVICETYPE_TOKEN_MANUALINIT				3
#define SDB_SERVICETYPE_TOKEN_FONT						10
#define	SDB_SERVICETYPE_TOKEN_UNLOCK					100
#define SDB_SERVICETYPE_TOKEN_UNLOCK_EX					101
#define	SDB_SERVICETYPE_ASYNC_AUTHENTICATION			200
#define	SDB_SERVICETYPE_SYNC_AUTHENTICATION				201
#define	SDB_SERVICETYPE_MINI_SYNC_AUTHENTICATION		202
#define	SDB_SERVICETYPE_EXT_SYNC_AUTHENTICATION			203
#define	SDB_SERVICETYPE_HOTP_AUTHENTICATION				204
#define	SDB_SERVICETYPE_SECRETVALUE_EXTRACTION			300
#define	SDB_SERVICETYPE_ASYNC_CERTIFICATION				400
#define	SDB_SERVICETYPE_SYNC_CERTIFICATION				401
#define	SDB_SERVICETYPE_EXTENDED_ASYNC_CERTIFICATION	402
#define	SDB_SERVICETYPE_EXTENDED_SYNC_CERTIFICATION		403
#define	SDB_SERVICETYPE_HOST_VERIFICATION				500
#define SDB_SERVICETYPE_STATIC_CREDENTIAL				600
#define SDB_SERVICETYPE_EMV_AUTH						700
#define	SDB_SERVICETYPE_KEY_EXCHANGE					1000
#define	SDB_SERVICETYPE_PIPAPIBLOB						1001
#define	SDB_SERVICETYPE_ENCAPSULATED_SDB				2000
#define SDB_SERVICETYPE_USER							0x8000

/* Service parts */
#define SDB_SERVICEPART_ALL				0
#define	SDB_SERVICEPART_COMMON			0x0001
#define	SDB_SERVICEPART_DEVICE_SPECIFIC	0x0002
#define	SDB_SERVICEPART_KERNEL_SPECIFIC	0x0004
#define	SDB_SERVICEPART_INFORMATION		0x0008
/* Bits from 0x0100 to 0x4000 are available for custom parts */
#define SDB_SERVICEPART_USER			0x0100

/* Crypto algo */
#define	SDB_CRYPTOALGO_NONE			0
#define	SDB_CRYPTOALGO_DES_ECB		1
#define	SDB_CRYPTOALGO_DES_CBC		2
#define	SDB_CRYPTOALGO_DES_EDE2		3
#define	SDB_CRYPTOALGO_DES_EDE2CBC	4

/* Crypto scope */
#define	SDB_CRYPTOSCOPE_PERSERVICE           0 /* Not yet implemented */
#define	SDB_CRYPTOSCOPE_GLOBALLY			 1
#define	SDB_CRYPTOSCOPE_GLOBALLY_WITH_HEADER 2

/* MAC algo */
#define	SDB_MACTYPE_NONE	    0
#define	SDB_MACTYPE_CRC16	    1
#define	SDB_MACTYPE_CRC32	    2
#define	SDB_MACTYPE_SHA1	    3   /* Not yet implemented */
#define	SDB_MACTYPE_ACMAC_SHA1	10
#define	SDB_MACTYPE_HMAC_SHA1	11
#define	SDB_MACTYPE_HMAC2104_SHA1	12  /* HMAC_SHA1 following RFC 2104 algorithm */

/* Some crypto methods */
#define SDB_CRYPTO_NONE				0
#define SDB_CRYPTO_CRC_ONLY			0x00020000
#define SDB_CRYPTO_DES_SHA1MAC		0x000A0101
#define SDB_CRYPTO_DESCBC_SHA1MAC	0x000A0102
#define SDB_CRYPTO_DES3_SHA1MAC		0x000A0103
#define SDB_CRYPTO_DES3CBC_SHA1MAC	0x000A0104
#define SDB_CRYPTO_DES_HMAC			0x000B0101
#define SDB_CRYPTO_DESCBC_HMAC		0x000B0102
#define SDB_CRYPTO_DES3_HMAC		0x000B0103
#define SDB_CRYPTO_DES3CBC_HMAC		0x000B0104
#define SDB_CRYPTO_DES_HMAC2104		0x000C0101
#define SDB_CRYPTO_DESCBC_HMAC2104	0x000C0102
#define SDB_CRYPTO_DES3_HMAC2104	0x000C0103
#define SDB_CRYPTO_DES3CBC_HMAC2104	0x000C0104


/* Useful macros to construct/get crypto method values */
#define SDB_MAKE_CRYPTOMETHOD(CryptoAlgo,CryptoScope,MACAlgo)	(	\
	((unsigned int)(MACAlgo) << 16) | \
	((unsigned int)(CryptoScope) << 8) | ((unsigned int)(CryptoAlgo)) \
	)
#define SDB_GET_CRYPTOALGO(CryptoMethod)	(CryptoMethod & 0x000000FF)
#define SDB_GET_CRYPTOSCOPE(CryptoMethod)	((CryptoMethod >> 8)& 0x000000FF)
#define SDB_GET_MACALGO(CryptoMethod)		((CryptoMethod >> 16)& 0x000000FF)

/* Accessors to retrieve the various parts of the version */
#define SDB_MAJOR_VERSION(x)		ACM_MAJOR_VERSION(x)
#define SDB_MINOR_VERSION(x)		ACM_MINOR_VERSION(x)
#define SDB_BUILD_VERSION(x)		ACM_BUILD_VERSION(x)

#define SDB_VERSION_VERSIONLEN		ACM_VERS_VERSIONLEN
#define SDB_VERSION_COPYRIGHTLEN	ACM_VERS_COPYRIGHTLEN
#define SDB_VERSION_COMMENTLEN		ACM_VERS_COMMENTLEN

/* Error codes */
enum {
    SDB_ERR_NOERROR             = 0,
    SDB_ERR_INTERNALERROR       = 1,
    SDB_ERR_NOTYETIMPLEMENTED   = 2,

    SDB_ERR_BADMAGICNUMBER      = 10,
    SDB_ERR_WRONGSDBVERSION     = 11,
    SDB_ERR_INVALIDSDB          = 12,
    SDB_ERR_MEMORYALLOCFAILURE  = 13,
    SDB_ERR_INCOMPATIBLESDB     = 14,	/* SDBSet */
    SDB_ERR_WRONGSIZE           = 15,	/* SDBSet(Get)RawServiceData */
    SDB_ERR_WRONGBYTEORDER      = 16,	/* SDBSet/SDBSetRawServiceData */
	SDB_ERR_INCOMPATIBLE_SERVICE= 17,

    SDB_ERR_EMPTY_SDB           = 20,
    SDB_ERR_ENDOFENUMERATION    = 21,
    SDB_ERR_BADPARAM            = 22,

    SDB_ERR_WRONG_KEY           = 30,
    SDB_ERR_WRONG_MAC           = 31,
    SDB_ERR_NEEDKEY             = 32,
    SDB_ERR_NONCRYPTO_LIB       = 33,	/* SDB API lib version without crypto */
    SDB_ERR_CRYPTO              = 34,

    SDB_ERR_SERVICENOTFOUND     = 40,
    SDB_ERR_SERVICEPARTNOTFOUND = 41,	/* SDBGetRawServiceData */

    SDB_ERR_IO_ERROR            = 50,
    SDB_ERR_NO_MORE_DATA        = 51,
    SDB_ERR_WRONG_SDBFILE       = 52,
	SDB_ERR_INCOMPATIBLE_FUNC	= 53	/* Function incompatible  with SDB content */
};


/**********************/
/** TYPE DEFINITIONS **/
/**********************/
typedef unsigned char *SDB;

typedef SDB *PSDB;


/***************/
/** FUNCTIONS **/
/***************/
int CALLBACK SDBNew(
		OUT PSDB pSdb,
		IN unsigned char *pRawSDB,
		IN int RawSDBLength);

int CALLBACK SDBFree(
		INOUT PSDB pSdb);

int CALLBACK SDBDuplicate(
        IN const char *pszKey, 
        IN PSDB pSrcSDB, 
        OUT PSDB pCloneSDB);


/* SDB Custom services functions */

int CALLBACK SDBSetInfoEx(
        IN const char *pszKey,
        INOUT PSDB pSDB,
        IN unsigned int *punContentType,
        IN char *pszContentID,
		IN unsigned int *punDeviceType,
        IN unsigned int *punContentRevNumber);

int CALLBACK SDBSetServiceInfo(
        IN const char *pszKey,
        INOUT PSDB pSDB,
        IN unsigned int ServiceType,
        IN const char *pszServiceName,
        IN unsigned short ServiceTarget,
        IN unsigned short ServiceStatus);

int CALLBACK SDBSetRawServiceData(
        IN const char *pszKey,
        INOUT PSDB pSdb,
        IN unsigned int ServiceType,
        IN const char *pszServiceName,
        IN unsigned short ServiceTarget,
        IN unsigned short ServiceStatus,
        IN unsigned short ServicePart,
        IN unsigned char *pRawData, 
        IN int RawDataLength);

int CALLBACK SDBGetRawServiceData(
        IN const char *pszKey, 
        IN PSDB pSdb,
        IN unsigned int ServiceType, 
        IN const char *pszServiceName,
        IN unsigned short ServicePart,
        OUT unsigned char *pRawData,
        INOUT int *pRawDataLength,
        OUT int *pRawServiceDataPlatform);

/* Encryption functions */
int CALLBACK SDBCipher(
        IN const char *pszKey, 
        IN unsigned int CryptoMethod,
        IN unsigned int CryptoParam, 
        INOUT PSDB pSDB);


/* SDB service block management */
/* Service per service */
int CALLBACK SDBSet(
        IN const char *pszKey, 
        INOUT PSDB pMainSDB,
        IN PSDB pSDBtoSet);

int CALLBACK SDBGet(
        IN const char *pszKey,
        IN PSDB pMainSDB,
        IN unsigned int ServiceType,
        IN const char *pszServiceName,
        IN unsigned short ServicePart,
        OUT PSDB pSDBGet);

int CALLBACK SDBDelete(
        IN const char *pszKey, 
        INOUT PSDB pSdb,
        IN unsigned int ServiceType, 
        IN const char *pszServiceName,
        IN unsigned short ServicePart);

/* Globally on all the services of a SDB */
int CALLBACK SDBSplit(
        IN const char *pszKey, 
        IN PSDB pMainSDB,
        IN unsigned short ServicePart, 
        IN unsigned short ServiceTarget,
        OUT PSDB pSDBResult);

/* Read accessors */
int CALLBACK SDBGetLen(
        IN const char *pszKey, 
        IN PSDB pSdb, 
        OUT int *pLen);

int CALLBACK SDBGetNbOfServices(
        IN const char *pszKey, 
        IN PSDB pSdb, 
        OUT int *pNbOfServices);

int CALLBACK SDBGetCryptoInfo(
        IN const char *pszKey, 
        IN PSDB pSdb,
        OUT unsigned int *pCryptoMethod,
        OUT unsigned int *pCryptoParam);

int CALLBACK SDBGetInfoEx(
        IN const char *pszKey, 
        IN PSDB pSdb,
        OUT unsigned int *pContentType,
        OUT char *pszContentID,
		INOUT unsigned int *pnContentIDLen,
		OUT unsigned int *pnDeviceType,
        OUT unsigned int *pContentRevNumber, 
        OUT int *pNbOfServices,
        OUT int *pLen);

int CALLBACK SDBGetServiceInfo(
        IN const char *pszKey, 
        IN PSDB pSdb,
        IN unsigned int ServiceType,
        IN const char *pszServiceName,
        OUT unsigned short *pServicePart,
        OUT unsigned short *pServiceTarget,
        OUT unsigned short *pServiceStatus);

int CALLBACK SDBEnumerate(
        IN const char *pszKey, 
        IN PSDB pSdb,
        INOUT unsigned int *pServiceType, 
        INOUT char *pszServiceName,
        OUT unsigned short *pServicePart, 
        OUT unsigned short *pServiceTarget,
        OUT unsigned short *pServiceStatus);

int CALLBACK SDBGetVersion(
        OUT char *pszVersion,
        OUT unsigned int *pVersion,
        OUT char *pszCopyright, 
        OUT char *pszComment);

/* Deprecated */

/* Platform where the SDB was created (for SDBGetRawServiceData) */
#define SDB_PLATFORM_LITTLE_ENDIAN	0	/* Intel */
#define SDB_PLATFORM_BIG_ENDIAN		1	/* Motorola */

/* Key exchange method */
#define SDB_KEYEXCHANGE_DIFFIE_HELLMAN  1

int CALLBACK SDBSetInfo(
        IN const char *pszKey,
        INOUT PSDB pSDB,
        IN unsigned int ContentType,
        IN unsigned char *pContentID,
        IN unsigned int ContentRevNumber);

int CALLBACK SDBGetInfo(
        IN const char *pszKey, 
        IN PSDB pSdb,
        OUT unsigned int *pContentType,
        OUT unsigned char *pContentID,
        OUT unsigned int *pContentRevNumber, 
        OUT int *pNbOfServices,
        OUT int *pLen);

#ifdef __cplusplus
}
#endif

#endif /* __SDBAPI_H__ */
